﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using MDS = TrueCloud.SF.DocoTool.Salesforce.Metadata.WebService;
using System.Windows.Forms;

namespace TrueCloud.SF.DocoTool
{
    class Metadata
    {
        public Metadata()
        {
        }
       
        public StringCollection getMetadataParentDescription()
        {
            StringCollection sResults = new StringCollection();
            try
            {
                MDS.DescribeMetadataResult mResult = Global.MDSoapClient.describeMetadata(Global.MDSessionHeader, Global.MDCallOptions, Const.SFVERSION);

                foreach (MDS.DescribeMetadataObject mo in mResult.metadataObjects)
                {
                    sResults.Add(mo.xmlName);
                }
                
            }
            catch (System.ServiceModel.FaultException fe)
            {
                MessageBox.Show(fe.Message, "Metadata Service Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return sResults;
            }
            catch (Exception)
            {
                throw;
            }

            return sResults;
        }

        //public StringCollection getMetadataChildDescription(string parent)
        //{
        //    StringCollection sResults = new StringCollection();
        //    try
        //    {
        //        MDS.DescribeMetadataResult mResult = Global.MDSoapClient.describeMetadata(Global.MDSessionHeader, Global.MDCallOptions, Const.SFVERSION);
        //        foreach (MDS.DescribeMetadataObject mo in mResult.metadataObjects)
        //        {
        //            //sResults.Add("DN:" + mo.directoryName + " /XML:" + mo.xmlName + " /SF:" + mo.suffix);
        //            sResults.Add(mo.xmlName);
        //        }
        //    }
        //    catch (System.ServiceModel.FaultException fe)
        //    {
        //        MessageBox.Show(fe.Message, "Metadata Service Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        //        return sResults;
        //    }
        //    catch (Exception)
        //    {
        //        throw;
        //    }

        //    return sResults;
        //}
        
        //public StringCollection getComponenetDescription(string component)
        //{
        //    StringCollection sResults = new StringCollection();
        //    MDS.ListMetadataQuery mListQuery = new MDS.ListMetadataQuery();
        //    mListQuery.type = component; //"WorkflowRule";//"ReportFolder";//

        //    MDS.ListMetadataQuery[] mListQueries = new MDS.ListMetadataQuery[] { mListQuery };
        //    try
        //    {
        //        MDS.FileProperties[] lmr = Global.MDSoapClient.listMetadata(Global.MDSessionHeader, Global.MDCallOptions, mListQueries, Const.SFVERSION);
        //        foreach (MDS.FileProperties fp in lmr)
        //        {
        //            sResults.Add(fp.fullName);
                    
        //        }
        //    }
        //    catch (System.ServiceModel.FaultException fe)
        //    {
        //        MessageBox.Show(fe.Message, "Metadata Service Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        //        return sResults;
        //    }
        //    catch (Exception)
        //    {
        //        throw;
        //    }

            
        //    return sResults;
        //}

        public String[] retrieveComponentsInFolders()
        {
            // can't use wildcards with reports, so need to fetch the list
            // of ReportFolders first, then fetch all the reports in
            // each folder.
            MDS.ListMetadataQuery q = new MDS.ListMetadataQuery();
            q.type = "ReportFolder";
            MDS.FileProperties[] fp = Global.MDSoapClient.listMetadata(Global.MDSessionHeader,Global.MDCallOptions, new MDS.ListMetadataQuery[] { q },Const.SFVERSION);
            if (fp == null)
            {
                Console.WriteLine("No report folders returned");
                return new String[0];
            }
            List<string> reportFiles = new List<string>();
            q.type = "Report";
            foreach (MDS.FileProperties p in fp)
            {
                q.folder = p.fullName;
                // listMetadata can take more than one item at a time
                // left as an exercise for the reader to batch up these calls.
                MDS.FileProperties[] rps = Global.MDSoapClient.listMetadata(Global.MDSessionHeader, Global.MDCallOptions, new MDS.ListMetadataQuery[] { q }, Const.SFVERSION);
                if (fp == null) continue;
                if (rps != null)
                {
                    foreach (MDS.FileProperties rp in rps)
                    {
                        Console.WriteLine("{0}", rp.fileName);
                        reportFiles.Add(rp.fullName);
                    }
                }
            }
            return reportFiles.ToArray();
        }

        public void retrieveComponents(String[] components, TextBox tb)
        {
            // one second in milliseconds 
            int onesecond = 1000;
            // maximum number of attempts to retrieve the results 
            int maxpolls = 6; 
            
            // build up an unpackaged retrieve request for the list of reports.
            MDS.RetrieveRequest r = new MDS.RetrieveRequest();
            r.apiVersion = Const.SFVERSION;
            r.unpackaged = new MDS.Package();
            MDS.PackageTypeMembers m = new MDS.PackageTypeMembers();
            m.name = "Workflow";
            //m.name = "Report";
            m.members = components;
            r.unpackaged.types = new MDS.PackageTypeMembers[] { m };

            // start the retrieve request
            MDS.AsyncResult ar =  Global.MDSoapClient.retrieve(Global.MDSessionHeader, Global.MDCallOptions, r);
            // wait for it to complete, sleeping as necassary.
            int poll = 0;
            int waitTimeMilliSecs = onesecond;
            while (!ar.done)
            {
                System.Threading.Thread.Sleep(waitTimeMilliSecs);
                ar = Global.MDSoapClient.checkStatus(Global.MDSessionHeader, Global.MDCallOptions, new String[] { ar.id })[0];
                tb.Text="Status is: " + ar.state + Environment.NewLine;
                Console.WriteLine("Status is: " + ar.state);
                waitTimeMilliSecs = waitTimeMilliSecs * 2;
                poll++;
                if (poll > maxpolls)
                {
                    throw new Exception("Request timed out.  If this is a large set " +
                         "of metadata components, check that the time allowed " +
                         "by MAX_NUM_POLL_REQUESTS is sufficient.");
                }
                
            }

            // did it work ?
            if (ar.state == MDS.AsyncRequestState.Error)
                Console.WriteLine("{0} {1}", ar.statusCode, ar.message);
            else
            {
                // now actually go get the results 
                MDS.RetrieveResult rr = Global.MDSoapClient.checkRetrieveStatus(Global.MDSessionHeader, Global.MDCallOptions, ar.id);
                if (rr.messages != null)
                    foreach (MDS.RetrieveMessage rm in rr.messages)
                        Console.WriteLine("{0} : {1}", rm.fileName, rm.problem);

                // write the zipFile out to a disk file.
                using (System.IO.FileStream fs = new System.IO.FileStream("c:\\sf\\reports.zip", System.IO.FileMode.Create))
                    fs.Write(rr.zipFile, 0, rr.zipFile.Length);
            }
        }   



    } 
}
